package com.sunwayworld.basemodule.business.ordertask.io;

import com.sunwayworld.basemodule.business.ordertask.bean.ExcelMessageDTO;
import com.sunwayworld.basemodule.business.ordertask.bean.LimsOrderTaskBean;
import com.sunwayworld.basemodule.business.ordertask.bean.LimsRunBoardHoleBean;
import com.sunwayworld.basemodule.business.ordertask.service.LimsOrderTaskService;
import com.sunwayworld.basemodule.business.ordertask.service.LimsRunBoardHoleService;
import com.sunwayworld.basemodule.business.result.bean.LimsRunBean;
import com.sunwayworld.basemodule.business.result.service.LimsRunService;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.io.file.FilePathManager;
import com.sunwayworld.framework.mybatis.mapper.MapperParameter;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.ArrayUtils;
import com.sunwayworld.framework.utils.ServletUtils;
import com.sunwayworld.framework.utils.StringUtils;
import com.sunwayworld.module.item.file.bean.CoreFileBean;
import com.sunwayworld.module.item.file.bean.CoreFileImportResultDTO;
import com.sunwayworld.module.item.file.function.CoreFileImportFunction;
import com.sunwayworld.module.item.file.utils.CoreFileUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@GikamBean
@Component(value = "limsRunBoardHoleImportFileFunction")
public class LimsRunBoardHoleImportFileFunction implements CoreFileImportFunction {

    @Autowired
    @Lazy
    private LimsRunService runService;

    @Autowired
    @Lazy
    private LimsRunBoardHoleService runBoardHoleService;

    @Autowired
    @Lazy
    private LimsOrderTaskService orderTaskService;

    @Override
    public CoreFileImportResultDTO apply(CoreFileBean coreFileBean) {
        CoreFileImportResultDTO resultDTO = new CoreFileImportResultDTO();
        List<ExcelMessageDTO> exportMapMsg = new ArrayList<>();
        String runCode = ServletUtils.getCurrentRequest().getParameter("runCode");
        List<LimsRunBean> runBeans = runService.getDao().selectListByOneColumnValue(runCode, "runCode");
        if (runBeans.isEmpty()) {
            throw new InvalidDataException("批次编号不存在:"+runCode);
        }
        LimsRunBean runBean = runBeans.get(0);
        Long testId = runBean.getTestId();
        MapperParameter temp = new MapperParameter();
        temp.setFilter(SearchFilter.instance().match("status","draft").filter(MatchPattern.EQ));
        temp.setFilter(SearchFilter.instance().match("testId",testId).filter(MatchPattern.EQ));
        temp.setFilter(SearchFilter.instance().match("addInRun","0").filter(MatchPattern.EQ));
        temp.setFilter(SearchFilter.instance().match("flag","1").filter(MatchPattern.EQ));
        List<LimsOrderTaskBean> orderTaskBeans = orderTaskService.selectList(temp);
        if (orderTaskBeans.isEmpty()){
            throw new InvalidDataException("当前工序未查询到待分批样本！");
        }

        HSSFWorkbook workbook = null;
        try{
            FileInputStream in = new FileInputStream(FilePathManager.getLocalPath(CoreFileUtils.toFilePath(coreFileBean)).toString());
            workbook = new HSSFWorkbook(in);
            HSSFSheet sheet = workbook.getSheetAt(0);

            HSSFRow runRow = sheet.getRow(1);
            HSSFCell runRowCell = runRow.getCell(1);
            if (runRowCell == null || StringUtils.isBlank(runRowCell.getStringCellValue())) {
                throw new InvalidDataException("导入批次编号为空！");
            }
            String excelRunCode = runRowCell.getStringCellValue();
            if (!excelRunCode.contains(runCode)){
                throw new InvalidDataException("选中批次编号与导入文件批次编号不一致！");
            }

            readExcelData(exportMapMsg,sheet);

            if (exportMapMsg.isEmpty()){
                throw new InvalidDataException("导入样本信息为空！");
            }

            List<String> sampleCodes = new ArrayList<>();
            List<String> holeList = new ArrayList<>();
            if (!exportMapMsg.isEmpty()){
                exportMapMsg.forEach(msg -> {
                    if (sampleCodes.contains(msg.getSampleCode())){
                        holeList.add(msg.getHoleNo());
                    }else{
                        sampleCodes.add(msg.getSampleCode());
                    }
                });
            }

            if (!holeList.isEmpty()){
                throw new InvalidDataException("以下孔号样本重复:"+StringUtils.join(holeList,","));
            }

            List<String> sysSampleCodes = orderTaskBeans.stream().map(LimsOrderTaskBean::getSampleCode).collect(Collectors.toList());
            holeList.clear();
            exportMapMsg.forEach(e -> {
                if (!sysSampleCodes.contains(e.getSampleCode())){
                    holeList.add(e.getSampleCode());
                }
            });
            if (!holeList.isEmpty()){
                throw new InvalidDataException("当前工序不存在以下样本:"+StringUtils.join(holeList,","));
            }
            List<LimsRunBoardHoleBean> holeBeans = runBoardHoleService.getDao().selectListByOneColumnValue(runBean.getId(), "boardId");
            List<String> allHoles = exportMapMsg.stream().map(ExcelMessageDTO::getHoleNo).collect(Collectors.toList());
            List<String> usedHoles = new ArrayList<>();
            holeBeans.forEach(hb -> {
                String holeNo = (char) (hb.getY() + 64) + String.format("%02d",hb.getX());
                if (allHoles.contains(holeNo) && !"free".equals(hb.getStockType())){
                    usedHoles.add(holeNo);
                }
            });
            if (!usedHoles.isEmpty()){
                throw new InvalidDataException("以下孔位被占用："+StringUtils.join(usedHoles,","));
            }
            List<LimsOrderTaskBean> updateSampleBeans = new ArrayList<>();
            List<LimsRunBoardHoleBean> updateLocationHoleBeans = new ArrayList<>();

            List<String> sampleCodeList = exportMapMsg.stream().map(ExcelMessageDTO::getSampleCode).collect(Collectors.toList());
            List<LimsOrderTaskBean> taskBeans = orderTaskBeans.stream().filter(ot -> sampleCodeList.contains(ot.getSampleCode())).collect(Collectors.toList());
            // 给每个样本 分配孔位
            for (int i = 0; i < taskBeans.size(); i++) {
                LimsOrderTaskBean orderTaskBean = orderTaskBeans.get(i);

                LimsRunBoardHoleBean holeBean = holeBeans.get(i);
                holeBean.setOrderTaskId(orderTaskBean.getId());
                holeBean.setStockType("in");
                if ("0".equals(orderTaskBean.getExt$Item("qcsampleflg"))){ // 实验样本
                    holeBean.setSampleFlag("0");
                }else{
                    holeBean.setSampleFlag("1");
                }
                updateLocationHoleBeans.add(holeBean);
                orderTaskBean.setBoardHoleId(holeBean.getId());
                // 增加到批
                orderTaskBean.setAddInRun("1");
                orderTaskBean.setRunCode(runBean.getRunCode());
                orderTaskBean.setRunId(runBean.getId());
                updateSampleBeans.add(orderTaskBean);

            }
            orderTaskService.getDao().fastUpdate(updateSampleBeans,  "runCode","runId","addInRun","boardHoleId");
            runBoardHoleService.getDao().fastUpdate(updateLocationHoleBeans, "orderTaskId", "stockType","sampleFlag");

            resultDTO.setMessage("success");
            return resultDTO;
        }catch (IOException e){
            e.printStackTrace();
        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    private void readExcelData(List<ExcelMessageDTO> itemList, HSSFSheet sheet) {
        for (int rowNo = 4; rowNo < sheet.getPhysicalNumberOfRows(); rowNo++){
            HSSFRow row = sheet.getRow(rowNo);
            String y = row.getCell(1).getStringCellValue();
            for (int cellNo = 2; cellNo < row.getPhysicalNumberOfCells(); cellNo++){
                HSSFCell cell = row.getCell(cellNo);
                if (cell == null || StringUtils.isBlank(cell.getStringCellValue())){
                    continue;
                }
                ExcelMessageDTO item = new ExcelMessageDTO();
                String sampleCode = cell.getStringCellValue();
                item.setSampleCode(sampleCode);
                item.setHoleNo(y + String.format("%02d", cellNo-1));
                itemList.add(item);
            }
        }
    }

    @Override
    public boolean test(CoreFileBean coreFile, String service) {
        return true;
    }
}
